package team.seekers.hula.island.islandUser.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import team.seekers.hula.auth.service.MindUtils;
import team.seekers.hula.common.entity.PageResult;
import team.seekers.hula.island.island.service.IslandService;
import team.seekers.hula.island.islandUser.dao.IslandUserDao;
import team.seekers.hula.island.islandUser.entity.dao.IslandUserDO;
import team.seekers.hula.island.islandUser.entity.dto.*;
import team.seekers.hula.island.islandUser.entity.vo.IslandUserListVO;
import team.seekers.hula.island.islandUser.entity.vo.IslandUserManagePageVO;
import team.seekers.hula.user.user.entity.dao.UserDO;
import team.seekers.hula.user.user.service.UserService;
import team.seekers.hula.user.userFollow.entity.vo.UserFollowInfoVO;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class IslandUserService{

    @Autowired
    private UserService userService;

    @Autowired
    @Lazy
    private IslandService islandService;

    @Autowired
    private IslandUserDao islandUserDao;


    public Map<String,IslandUserListVO> mapByUserIdAndIslandIds(IslandUserListDTO listDTO) {
        HashMap<String, IslandUserListVO> map = new HashMap<>();

        LambdaQueryChainWrapper<IslandUserDO> query = islandUserDao.lambdaQuery().eq(IslandUserDO::getUserId, listDTO.getUserId());

        if(listDTO.getRole() != null){
            query.eq(IslandUserDO::getRole,listDTO.getRole());
        }

        if(listDTO.getIsFixed() != null){
            query.eq(IslandUserDO::getIsFixed,listDTO.getIsFixed());
        }

        List<IslandUserDO> islandUserDOS = query.list();
        for (IslandUserDO record : islandUserDOS) {
            IslandUserListVO build = IslandUserListVO.builder()
                    .role(record.getRole())
                    .isFixed(record.getIsFixed())
                    .userId(record.getId())
                    .hulaCoin(record.getHulaCoin())
                    .gmtCreate(record.getGmtCreate()).build();
            map.put(record.getIslandId(),build);
        }
        return map;
    }

    @Transactional
    public void updateRole(IslandUserUpdateDTO islandUserUpdateDTO) {
        IslandUserDO islandUserDO = new IslandUserDO();
        islandUserDO.setId(islandUserUpdateDTO.getId());
        islandUserDO.setRole(islandUserUpdateDTO.getRole());
        islandUserDao.updateById(islandUserDO);
    }

    @Transactional
    public void batchBind(IslandUserBatchBindDTO islandUserBatchBindDTO) {
        List<IslandUserDO> islandUserDOS = new ArrayList<>();
        for (String islandId : islandUserBatchBindDTO.getIslandIds()) {
            for (String userId : islandUserBatchBindDTO.getUserIds()) {
                IslandUserDO islandUserDO = new IslandUserDO();
                islandUserDO.setIslandId(islandId);
                islandUserDO.setUserId(userId);
                islandUserDO.setRole(islandUserBatchBindDTO.getRole());
                islandUserDOS.add(islandUserDO);
            }

            // 去重
            List<IslandUserDO> exists = islandUserDao.lambdaQuery()
                    .in(IslandUserDO::getUserId, islandUserBatchBindDTO.getUserIds())
                    .eq(IslandUserDO::getIslandId, islandId).list();
            islandUserDOS.removeAll(exists);
        }
        islandUserDao.saveOrUpdateBatch(islandUserDOS);
    }

    @Transactional
    public void unbind(String userId, String islandId) {
        LambdaQueryWrapper<IslandUserDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(IslandUserDO::getUserId, userId);
        queryWrapper.eq(IslandUserDO::getIslandId, islandId);
        islandUserDao.remove(queryWrapper);
    }


    /**
     * 查询已购买数量
     */
    public Integer countBuy(String id) {
        return islandUserDao.lambdaQuery().eq(IslandUserDO::getIslandId,id).count();
    }

    /**
     * 查询已常驻数量
     */
    public Integer countFixed(String id) {
        return islandUserDao.lambdaQuery().eq(IslandUserDO::getIslandId,id).eq(IslandUserDO::getIsFixed,1).count();
    }

    /**
     * 改变记忆浪屿的剩余刻入数量
     */
    public void changeCount(String islandId, String userId, int count) {
        IslandUserDO islandUserDO = islandUserDao.lambdaQuery()
                .select(IslandUserDO::getCount,IslandUserDO::getId)
                .eq(IslandUserDO::getIslandId, islandId)
                .eq(IslandUserDO::getUserId, userId)
                .one();
        islandUserDO.setCount(islandUserDO.getCount()+count);
        islandUserDao.updateById(islandUserDO);
    }

    public List<String> getFixedIslandIds(String userId) {
        List<IslandUserDO> islandUserDOList = islandUserDao.lambdaQuery()
                .select(IslandUserDO::getIslandId)
                .eq(IslandUserDO::getIsFixed, 1)
                .eq(IslandUserDO::getUserId, userId)
                .list();

        ArrayList<String> islandIds = new ArrayList<>();
        for (IslandUserDO islandUserDO : islandUserDOList) {
            islandIds.add(islandUserDO.getIslandId());
        }
        return islandIds;
    }

    public List<String> getIslandIds(String userId) {
        List<IslandUserDO> islandUserDOList = islandUserDao.lambdaQuery()
                .select(IslandUserDO::getIslandId)
                .eq(IslandUserDO::getUserId, userId)
                .list();

        ArrayList<String> islandIds = new ArrayList<>();
        for (IslandUserDO islandUserDO : islandUserDOList) {
            islandIds.add(islandUserDO.getIslandId());
        }
        return islandIds;
    }

    public Map<String, IslandUserManagePageVO> mapIslandIdsAndJoinStatus(ArrayList<String> islandIds, String userId) {
        List<IslandUserDO> islandUserDOList = islandUserDao.lambdaQuery()
                .select()
                .eq(IslandUserDO::getUserId, userId)
                .in(IslandUserDO::getIslandId, islandIds)
                .list();

        HashMap<String, IslandUserManagePageVO> map = new HashMap<>();

        for (IslandUserDO record : islandUserDOList) {
            UserDO userDO = userService.getById(record.getUserId());
            IslandUserManagePageVO build = IslandUserManagePageVO.builder()
                    .nickname(userDO.getNickname())
                    .role(record.getRole())
                    .tel(userDO.getTel())
                    .userId(record.getId())
                    .hulaCoin(record.getHulaCoin())
                    .gmtCreate(record.getGmtCreate()).build();
            map.put(record.getIslandId(),build);
        }
        return map;
    }

    public void bind(IslandUserBindDTO islandUserBindDTO) {

        Integer type = islandService.getTypeById(islandUserBindDTO.getIslandId());

        IslandUserDO islandUserDO = IslandUserDO
                .builder()
                .userId(islandUserBindDTO.getUserId())
                .islandId(islandUserBindDTO.getIslandId()).role(0)
                .count(type == 0 ? 1 :0)
                .build();
        islandUserDao.save(islandUserDO);

    }

    public void fixedOrCancel(String islandId, String userId) {
        IslandUserDO islandUserDO = islandUserDao.lambdaQuery().select(IslandUserDO::getId, IslandUserDO::getIsFixed)
                .eq(IslandUserDO::getIslandId, islandId).eq(IslandUserDO::getUserId, userId).one();

        islandUserDO.setIsFixed(islandUserDO.getIsFixed() == 1 ? 0 : 1);
        islandUserDao.updateById(islandUserDO);
    }

    public boolean isBuy(String islandId, String userId) {
        return islandUserDao.lambdaQuery().eq(IslandUserDO::getIslandId,islandId).eq(IslandUserDO::getUserId,userId).count() > 0;
    }

    public Boolean isFixed(String islandId, String userId) {
        IslandUserDO islandUserDO = islandUserDao.lambdaQuery().eq(IslandUserDO::getIslandId, islandId).eq(IslandUserDO::getUserId, userId).one();
        if(islandUserDO != null){
            return islandUserDO.getIsFixed() > 0;
        }else {
            return false;
        }

    }

    public PageResult<IslandUserListVO> pageUser(IslandUserPageDTO pageDTO) {
        Page<IslandUserDO> page = islandUserDao
                .lambdaQuery()
                .eq(IslandUserDO::getIslandId, pageDTO.getIslandId())
                .page(new Page<>(pageDTO.getPageNow(), pageDTO.getPageSize()));

        if(page.getRecords().size() == 0){
            return new PageResult<>();
        }

        ArrayList<String> userIds = new ArrayList<>();
        for (IslandUserDO record : page.getRecords()) {
            userIds.add(record.getUserId());
        }

        Map<String, UserFollowInfoVO> map = userService.idsMapFollowInfoVOList(userIds, MindUtils.getUserId());

        ArrayList<IslandUserListVO> listVOS = new ArrayList<>();
        for (IslandUserDO record : page.getRecords()) {
            IslandUserListVO islandUserListVO = new IslandUserListVO();
            BeanUtils.copyProperties(record,islandUserListVO);
            islandUserListVO.setUserInfo(map.get(record.getUserId()));
            listVOS.add(islandUserListVO);
        }

        return new PageResult<>(page.getTotal(),listVOS);
    }

    public List<String> getThreeUserAvatar(String islandId) {
        List<IslandUserDO> userDOS = islandUserDao
                .lambdaQuery()
                .select(IslandUserDO::getUserId)
                .eq(IslandUserDO::getIslandId, islandId)
                .last("limit 3").list();
        ArrayList<String> userIds = new ArrayList<>();
        for (IslandUserDO userDO : userDOS) {
            userIds.add(userDO.getUserId());
        }
        return userService.userIdsToAvatarList(userIds);
    }
}
